<template>
  <div class="component">
    <el-container>
      <el-aside style="width: 26%;border:1px solid #ddd;border-radius: 10px">
        <el-table :data="clusters" @row-click="handleRowClick" style="width: 100%;height: 100%;padding-left: 5px;">
          <el-table-column width="225">
            <template #default="scope">
              <div>
                <img :src="getCompsTypeIcon(scope.row.type)" style="vertical-align: middle; padding-right: 4px;"/>
                {{ scope.row.name }}
              </div>
            </template>
          </el-table-column>
          <el-table-column width="65">
            <template #default="scope">
              <el-tag :type="'danger'">{{getProgressNum(scope.row.clusterId,'fail')}}</el-tag>
            </template>
          </el-table-column>
          <el-table-column width="65">
            <template #default="scope">
              <el-tag :type="'warning'">{{getProgressNum(scope.row.clusterId,'waiting')}}</el-tag>
            </template>
          </el-table-column>
          <el-table-column width="65">
            <template #default="scope">
              <el-tag :type="'success'">{{getProgressNum(scope.row.clusterId,'success')}}</el-tag>
            </template>
          </el-table-column>
          <el-table-column width="40">
            <template #default="scope">
              <el-button type="text" style="padding-left:10px" @click.stop="showProgressDrawer(scope.row.clusterId)">
              <template #icon>
                <img src="../assets/next.png"/>
              </template>
            </el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-aside>
      <el-main style="height: 100%;padding-top: 0px;padding-right: 0px;">
        <div style="height: 5%;"><p style="font-size: large;">{{ selectedCluster.name }}</p></div>
        <el-table :data="nodes" default-expand-all="true">
          <el-table-column label="状态" width="100">
            <template #default="scope">
              <div>
                <img :src="getNodeStatusIcon(scope.row.status)" style="vertical-align: middle; padding-right: 4px;"/>
                <span>{{getNodeStatusTooltip(scope.row.status)}}</span>
              </div>
            </template>
          </el-table-column>
          <el-table-column label="ip" prop="ip" width="120"/>
          <el-table-column label="名称" prop="hostname" width="120"/>
          <el-table-column type="expand" default-expand-all="true">
            <template #default="scope">
              <div style="padding:20px;">
                <div>
                  <span style="font-size:20px">edh component services</span>
                  <el-button type="text" style="padding-left:10px" @click="stopWorker(scope.row.ip,scope.row.auths)">
                    <template #icon>
                      <el-tooltip content="stop services" placement="top">
                        <img src="../assets/stop.png"/>
                      </el-tooltip>
                    </template>
                  </el-button>
                  <el-button type="text" style="padding-left:5px" @click="startWorker(scope.row.ip,scope.row.auths)">
                    <template #icon>
                      <el-tooltip content="start services" placement="top">
                        <img src="../assets/start.png" style=""/>
                      </el-tooltip>
                    </template>
                  </el-button>
                </div>
                <ul>
                  <li>
                    <img :src="getServiceStatusIcon(scope.row.status)" style="vertical-align: middle; padding-right: 4px;"/>
                    <span>
                      worker
                    </span>
                  </li>
                </ul>
              </div>
              <div style="padding:20px;">
                <span style="font-size:20px">data component services</span>
                <el-button type="text" style="padding-left:10px" @click="stopDataComp(scope.row.ip,scope.row.roles)">
                  <template #icon>
                    <el-tooltip content="stop services" placement="top">
                      <img src="../assets/stop.png"/>
                    </el-tooltip>
                  </template>
                </el-button>
                <el-button type="text" style="padding-left:5px" @click="startDataComp(scope.row.ip,scope.row.roles)">
                  <template #icon>
                    <el-tooltip content="start services" placement="top">
                      <img src="../assets/start.png" style=""/>
                    </el-tooltip>
                  </template>
                </el-button>
                <ul>
                  <li v-for="(role,index) in scope.row.roles" :key="index">
                    <img :src="getServiceStatusIcon(role.status)" style="vertical-align: middle; padding-right: 4px;"/>
                    <span>{{ role.name }}</span>
                  </li>
                </ul>
              </div>
            </template>
          </el-table-column>
          <el-table-column label="角色" >
            <template #default="scope">
              <div>
                <span v-if="scope.row.roles!=undefined">{{scope.row.roles.length}} role(s)</span>
              </div>
            </template>
          </el-table-column>
          <el-table-column label="上一次心跳">
            <template #default="scope">
              <div>
                <span v-if="scope.row.timeout!=''">{{scope.row.timeout}}</span>
              </div>
            </template>
          </el-table-column>
          <el-table-column label="磁盘使用情况">
            <template #default="scope">
              <div>
                <span v-if="scope.row.usedDisk>0&&scope.row.totalDisk>0">{{scope.row.usedDisk}} / {{scope.row.totalDisk}} (MB)</span>
              </div>
              <div>
                <el-progress 
                v-if="scope.row.usedDisk>0&&scope.row.totalDisk>0" 
                  :percentage="scope.row.usedDisk/scope.row.totalDisk*100" 
                  :show-text="false"
                  status="success"
                  :stroke-width="10"/>
              </div>
            </template>
          </el-table-column>
          <el-table-column label="内存使用情况">
            <template #default="scope">
              <div>
                <span v-if="scope.row.usedMem>0&&scope.row.totalMem>0">{{scope.row.usedMem}} / {{scope.row.totalMem}} (MB)</span>
              </div>
              <div>
                <el-progress v-if="scope.row.usedMem>0&&scope.row.totalMem>0" 
                  :percentage="scope.row.usedMem/scope.row.totalMem*100" 
                  :show-text="false"
                  status="success"
                  :stroke-width="10"/>
              </div>
            </template>
          </el-table-column>
        </el-table>
      </el-main>
      <el-drawer v-model="showProgress" direction="rtl" :with-header="false">
        <el-timeline>
          <el-timeline-item
           v-for="(step,index) in selectedProgress.progress" 
          :key="index"
          :type="primary"
          :hollow="true"
          :color="'#5DE2E7'"
          >
          <div style="vertical-align: middle;">
            <span>{{ step.name }}</span>
            <img style="padding-left:10px" :src="getStepStatusIcon(step.status)"/>
          </div>
          </el-timeline-item>
        </el-timeline>
      </el-drawer>
    </el-container>
  </div>
</template>
<script>
import {ref} from 'vue'
import {inject } from 'vue';
import config from '@/configs/config'
export default {
  name: "ClusterView",
  setup(){
    const domain = ref("http://"+config.server.ip+":"+config.server.port)
    const clusters = ref([])
    const selectedCluster = ref({})
    const progressGroup = ref({})
    const progressStatus = ref({})
    const nodes = ref([])
    const showProgress=ref(false)
    const selectedProgress=ref([])
    const edsws = inject("$edsws")
    const getClusters=()=>{
      fetch(domain.value+"/clusters/getclusters")
      .then(clusterResp=>clusterResp.json())
      .then(clusterData=>{
        clusters.value=JSON.parse(clusterData.result)
        getProgress()
      })
    }

    const getProgress=()=>{
      clusters.value.forEach(cluster => {
        fetch(domain.value+"/clusters/getprogress?clusterId="+cluster.clusterId)
        .then(proResp=>proResp.json())
        .then(proData=>{
          let progress = JSON.parse(proData.result)
          let successNum = 0
          let waitingNum = 0
          let failNum = 0
          progress.forEach(element => {
            if (element.status==1){
              successNum ++
            }
            if(element.status==0){
              waitingNum ++
            }
            if(element.status==-1){
              failNum ++
            }
          });
          progressStatus.value[cluster.clusterId] = {"success":successNum,"waiting":waitingNum,"fail":failNum}
          progressGroup.value[cluster.clusterId]=progress
        })
      });
    }

    const getNodes=()=>{
      fetch(domain.value+"/clusters/getnodes?clusterId="+selectedCluster.value.clusterId)
      .then(response=>response.json())
      .then(nodeData=>{
        if(nodeData.result!=""){
          nodes.value=JSON.parse(nodeData.result)
          nodes.value.forEach(node=>{
            fetch(domain.value+"/clusters/getnodestatus?ip="+node.ip)
            .then(response=>response.json())
            .then(statusData=>{
              let stat = JSON.parse(statusData.result)
              node["status"] = stat.status
              node["timeout"] = stat.timeout
              node["usedMem"] = stat.usedMem
              node["totalMem"] = stat.totalMem
              node["usedDisk"] = stat.usedDisk
              node["totalDisk"] = stat.totalDisk
            })
            fetch(domain.value+"/clusters/getroles?clusterId="+selectedCluster.value.clusterId+"&ip="+node.ip+"&comp="+selectedCluster.value.comp)
            .then(response=>response.json())
            .then(rolesData=>{
              if(rolesData.result!=""){
                let roles = JSON.parse(rolesData.result)
                node["roles"] = roles
              }
              
            })
          })
        }
      })
    }


    const handleRowClick=(row)=>{
      selectedCluster.value = row
      getNodes()
    }

    const getCompsTypeIcon=(filename)=>{
      return require(`@/assets/${filename}.png`)
    }

    const getNodeStatusIcon=(status)=>{
      if(status==0){
        return require(`@/assets/warn.png`)
      }
      if(status==1){
        return require(`@/assets/pass.png`)
      }
    }

    const getServiceStatusIcon=(status)=>{
      if(status==0){
        return require(`@/assets/warn.png`)
      }
      if(status==1){
        return require(`@/assets/pass.png`)
      }
    }

    const getNodeStatusTooltip=(status)=>{
      if (status==0){
        return "离线"
      }
      if(status==1){
        return "在线"
      }
    }

    const getProgressNum=(clusterId,type)=>{
      if (progressStatus.value[clusterId]){
        return progressStatus.value[clusterId][type]
      }
    }

    const showProgressDrawer=(clusterId)=>{
      selectedProgress.value["clusterId"] = clusterId
      selectedProgress.value["progress"] = progressGroup.value[clusterId]
      showProgress.value=true
    }

    const getStepStatusIcon=(status)=>{
      if(status==1){
        return require(`@/assets/finish.png`)
      }
      if(status==0){
        return require(`@/assets/waiting_black.png`)
      }
      if(status==-1){
        return require(`@/assets/fail.png`)
      }
    }

    

    const wsMessageHandler=(message)=>{
      let msgJson = JSON.parse(message)
      if(selectedProgress.value["clusterId"]==msgJson["clusterId"]){
        selectedProgress.value["progress"][msgJson["index"]-1]["status"] = msgJson["status"]
      }
      getClusters()
      
    }

    const addWSMessageHandler=()=>{
      edsws.addMessageHandler(wsMessageHandler)
    }

    const startWorker=(ip,auths)=>{
      fetch(domain.value+"/clusters/startworker?addr="+ip+"&auths="+auths)
      .then(response=>response.json())
      .then(data=>{
        alert(data.msg)
        getNodes()
      })

    }
    const stopWorker=(ip,auths)=>{
      fetch(domain.value+"/clusters/stopworker?addr="+ip+"&auths="+auths)
      .then(response=>response.json())
      .then(data=>{
        alert(data.msg)
        getNodes()
      })
    }

    const startDataComp=(ip,roles)=>{
      let roleArr = []
      roles.forEach(role=>{
        roleArr.push(role.name)
      })
      fetch(domain.value+"/clusters/startdatacomp?addr="+ip+"&roles="+roleArr.join(",")+"&comp="+selectedCluster.value.comp)
      .then(response=>response.json())
      .then(data=>{
        alert(data.msg)
        getNodes()
      })
    }

    const stopDataComp=(ip,roles)=>{
      let roleArr = []
      roles.forEach(role=>{
        roleArr.push(role.name)
      })
      fetch(domain.value+"/clusters/stopdatacomp?addr="+ip+"&roles="+roleArr.join(",")+"&comp="+selectedCluster.value.comp)
      .then(response=>response.json())
      .then(data=>{
        alert(data.msg)
        getNodes()
      })
    }

    return{
      domain,
      clusters,
      nodes,
      selectedCluster,
      progressGroup,
      showProgress,
      selectedProgress,
      edsws,
      getClusters,
      getProgress,
      getNodes,
      handleRowClick,
      getCompsTypeIcon,
      getNodeStatusIcon,
      getServiceStatusIcon,
      getNodeStatusTooltip,
      showProgressDrawer,
      getStepStatusIcon,
      getProgressNum,
      wsMessageHandler,
      addWSMessageHandler,
      startWorker,
      stopWorker,
      startDataComp,
      stopDataComp
    }
  },
  mounted(){
    this.getClusters()
    this.addWSMessageHandler()
  }
}
</script>
<style lang="scss">

</style>


